<?php

set_time_limit(5);
class G_Chart  {

    //[Public access]
    var $root_id = 0;
	var $super_root_id = 0;
	var $width = null;
	var $max_level = 0;

	var $node_image_url = array();
	var $root_node_image_url = "";

	var $is_enable_placement = false;
	var $is_enable_leftright = false;
	var $db_info = array();

	var $img_path = "";
	var $img_url = "";

	var $ori_links = "";
	var $script = "";

	var $is_search = false;

	//[Private access]
	var $go_down_links = "";
	var $go_up_links = "";

	var $rank_name = array();

	var $downlines = array();
	var $total_nodes = 0;
    var $levels = array();
	var $level_num = 0;

	var $node_image_width = 0;
	var $node_image_height = 0;

	var $root_node_image_width = 0;
	var $root_node_image_height = 0;
	
	var $up_user_id = "";

	var $users = array();

	var $search_id = 0;

	function __construct($db_info) {
		$this->G_Chart($db_info);
	}

	function G_Chart($db_info) {
		$this->db_info = $db_info;
		$this->rank_name = $GLOBALS["_rank_index_a_d"];
	}

    function set_script($script_name) {
		$this->script = $script_name;
		return $this;
	}

    function set_links($links) {
		$this->ori_links = $links;
		return $this;
	}

    function set_img_path($img_path) {
		$this->img_path = $img_path;
		return $this;
	}

	function set_img_url($img_url) {
		$this->img_url = $img_url;
		return $this;
	}

    function set_super_root_id($super_root_id) {
		$this->super_root_id = (int)$super_root_id;
	    return $this;
	}

    function set_is_search($is_search) {

		$this->is_search = (bool)$is_search;
	    return $this;
	}

    function set_root_id($root_id) { 
		$this->root_id = (int)$root_id; 
		return $this;
	}

	function set_width ($width)      { 
		$this->width = (int)$width OR $this->width=null; 
		return $this;
	}

	function set_enable_placement($bool) {
        $this->is_enable_placement = $bool;
		return $this;
	}

	function set_enable_leftright($bool) {
        $this->is_enable_leftright = $bool;
		return $this;
	}

	function set_max_level ($level) { 
		$this->max_level = (int)$level;     		
		return $this;
	}
    
	function set_root_node_img($image_file) {
        $this->root_node_image_url = $this->img_url . $image_file;
		list($this->root_node_image_width,$this->root_node_image_height)=getimagesize($this->img_path . $image_file);
		return $this;
	}

	function set_rank_img($rank , $image_file) {
        $this->node_image_url[$rank] = $this->img_url . $image_file;

		if (!$this->node_image_width && !$this->node_image_height)
		    list($this->node_image_width,$this->node_image_height)=getimagesize($this->img_path . $image_file);
		return $this;
	}

    function get_all_uplines_in_single_path() {

		$root_id = $this->root_id;
		$positions = $root_ids = array();

		do {
			$r = mysql_query($sql="SELECT 
			                         {$this->db_info['parent_user_col']},
									 {$this->db_info['orderby_col']} 
			                       FROM {$this->db_info['table']} 
								   WHERE 
								     {$this->db_info['user_col']}='{$root_id}' AND 
									 {$this->db_info['user_col']}!='{$this->super_root_id}' AND 
									 {$this->db_info['orderby_col']}!=0".( !is_a($this, "CG_Chart") ? "
									 AND
									 {$this->db_info['orderby_col']} <= {$this->width}
								  " : "")) or die(mysql_error());

			if ( mysql_num_rows($r) ) {
				if ($row = mysql_fetch_row($r) ) {
					$root_ids[]  = $root_id = $row[0];
					$positions[] = $row[1];
				} else { break; }
            } else { break; }

		} while (true);

        return array($root_ids, $positions);
	}

	function process($upline_ids = 0) {


		//check root_id 
		$flag = true;

		if ($this->is_search) $this->search_id = $this->root_id;

		if (mysql_num_rows($r=mysql_query($sql="SELECT 
		                                            u2.{$this->db_info['user_col']},
													u2.id, u2.rank_a, u2.name as name
												FROM {$this->db_info['table']} u2
												WHERE u2.{$this->db_info['user_col']}='{$this->root_id}'"))) {

			//get this page's actual root ID if available
			if ( empty($this->ori_links) ) {

				//if this is empty, then we need to find its uplines and concat them 
				$uplines = $this->get_all_uplines_in_single_path();
				$upline_ids       = $uplines[0];
				$upline_positions = $uplines[1];

				$total_uplines = count($upline_ids);
      
				if ($total_uplines) {

					$total_pages = ceil( $total_uplines/$this->max_level );
					$total_pages -= 1;
					$total_nodes = $total_pages * $this->max_level;
					$root_pos    = $total_nodes + 1;
					$upline_ids       = array_reverse ($upline_ids);
					$upline_positions = array_reverse($upline_positions);

                    for($i=1; $i<=$total_nodes; $i+=$this->max_level) {
						$this->ori_links   .= $upline_ids[$i-1] . ",";
						$this->start_links .= $upline_positions[$i-1] . ",";
					}

					$this->ori_links   = rtrim($this->ori_links,",");
					$this->start_links = rtrim($this->start_links,",");

					$this->root_id = $upline_ids[$root_pos-1];

					$r = mysql_query($sql="SELECT 
					                           u2.{$this->db_info['user_col']},
											   u2.id, u2.rank_a, u2.name as name
										   FROM {$this->db_info['table']} u2
										   WHERE u2.{$this->db_info['user_col']}='{$this->root_id}'");

					if (!mysql_num_rows($r)) $flag = false;
				}
			}
		} else {
			$flag = false;
		}
		if (!$flag) { 
			echo "Root ID is not found,process terminated";
		} else {
			
			$row = mysql_fetch_assoc($r);
			$row["rank"] = $row['rank_a'];
			$row["total_downlines"] = (int)$this->get_total_downline_by_leg( $this->root_id );
			$this_month_starttime = mktime(0,0,0,ndate('n'),1,ndate('Y'));
			$this_month_endtime = mktime(23,59,59,ndate('n')+1,0,ndate('Y'));
			$date_start = date("Y-m-d H:i:s", $this_month_starttime);
			$date_end = date("Y-m-d H:i:s", $this_month_endtime);
			$row['sales_plana'] = number_format(@mysql_result(mysql_query($s="select sum(total_bv) from gg_purchase where uid='$this->root_id' and first_sale='y' and status='confirmed' and cdate>='$date_start' and cdate<='$date_end'"), 0), 2);
			$row['sales_planb'] = number_format(calc_personal_sales($this->root_id, $date_start, $date_end), 2);


			$this->users[$this->root_id] = $row;

			//do actions
			$this->do_link();
			$this->levelize();
			$this->do_position();
		}
	}

	function do_link() {

		if ( !empty($this->ori_links) ) {

			$user_ids = (array)@explode(",", $this->ori_links);
			$this->up_user_id = end($user_ids);

			$this->go_down_links = $this->ori_links . "," . $this->root_id ;				
			array_pop($user_ids);	
			$this->go_up_links = implode(",", $user_ids);

		} else {
			$this->go_down_links = $this->root_id;

		}

	}

	function levelize($upline_ids = 0) {

		$upline_ids = (!$upline_ids) ? "'{$this->root_id}'" : $upline_ids;
        if ($upline_ids == "''" || ($this->level_num >= $this->max_level && $this->max_level)) return false;
        $this->level_num++;
	    $sql = "SELECT        		        
		            {$this->db_info['parent_user_col']}, 
					COUNT(id) as total, 
					CONCAT('\'', GROUP_CONCAT({$this->db_info['user_col']} ORDER BY {$this->db_info['orderby_col']} ASC SEPARATOR '\',\''), '\''),
					CONCAT('\'',{$this->db_info['parent_user_col']},'\'', '=>Array(' , GROUP_CONCAT({$this->db_info['user_col']} ORDER BY {$this->db_info['orderby_col']} ASC SEPARATOR ','),')'),
					CONCAT('\'',{$this->db_info['parent_user_col']},'\'', '=>Array(' , GROUP_CONCAT({$this->db_info['orderby_col']} ORDER BY {$this->db_info['orderby_col']} ASC SEPARATOR ','),')')
				FROM {$this->db_info['table']} u2
				WHERE 
				  {$this->db_info['parent_user_col']} IN ({$upline_ids}) AND 
				  ({$this->db_info['orderby_col']} <= {$this->width} AND 
				  {$this->db_info['orderby_col']} != '0')
				GROUP BY {$this->db_info['parent_user_col']}
				ORDER BY {$this->db_info['orderby_col']}
					  ";

        $r = mysql_query($sql) or die(mysql_error());

        if (mysql_num_rows($r)) {

			$this_level =& $this->levels[$this->level_num]; 
			$this_level["downup_lines"] = array();
			$max_nodes = 0;

			while ($row = mysql_fetch_row($r)) {	
               
                $old_upline_ids = explode(",", $row[2]);

		        $next_upline_ids .=  "," . implode(",", $old_upline_ids);               
				$max_nodes = max($max_nodes, count($old_upline_ids) );
			    $updown_lines = $row[3];
				$updown_positions = $row[4];

                eval("\$uplines   = Array({$updown_lines});");  
				eval("\$positions = Array({$updown_positions});");

                $key = key($uplines);
				$uplines   = $uplines[$key];
				$positions = $positions[$key];

				//$uplines =  array_slice($uplines[$key],0,$this->width);

                $this_level["downup_lines"][$key] = array_combine($uplines, $positions);

				foreach ($uplines as $user_id) {

					$sql = "SELECT 
					          u2.id, u2.rank_a, u2.name as name
							FROM {$this->db_info['table']} u2
							WHERE u2.{$this->db_info['user_col']}='{$user_id}'";

					$row2 = mysql_fetch_assoc(mysql_query($sql));
					$row2["rank"] = $row2['rank_a'];
					$row2["total_downlines"] = (int)$this->get_total_downline_by_leg( $user_id );
					$this_month_starttime = mktime(0,0,0,ndate('n'),1,ndate('Y'));
					$this_month_endtime = mktime(23,59,59,ndate('n')+1,0,ndate('Y'));
					$date_start = date("Y-m-d H:i:s", $this_month_starttime);
					$date_end = date("Y-m-d H:i:s", $this_month_endtime);
					$row2['sales_plana'] = number_format(@mysql_result(mysql_query($s="select sum(total_bv) from gg_purchase where uid='$user_id' and first_sale='y' and status='confirmed' and cdate>='$date_start' and cdate<='$date_end'"), 0), 2);
					$row2['sales_planb'] = number_format(calc_personal_sales($user_id, $date_start, $date_end), 2);

				    $this->users[$user_id] = $row2;
				}
			}

			$next_upline_ids = ltrim($next_upline_ids,",");
			$this_level["max_nodes"] = $max_nodes;

        } else { 
			$next_upline_ids = "''"; 
		}
		$this->levelize( $next_upline_ids );
	}

	function get_total_downline_by_leg($downline_id){
		/*
		This function returns how many downline under a particular leg (downline_id) in a particular network
		*/

		$total_downline = 0;//echo '<pre>';
		$t=@mysql_num_rows($r=mysql_query($s="select {$this->db_info['user_col']} from {$this->db_info['table']} where {$this->db_info['parent_user_col']}='$downline_id' AND ({$this->db_info['orderby_col']} <= {$this->width} AND {$this->db_info['orderby_col']} != '0')"));

		for($i=0;$i<$t;$i++){
			$member=mysql_fetch_assoc($r);
			$all_downlines[$member["id"]]=$member;
			$uplines[$i]=$member["id"];
		}

		if(count($uplines)){
			do{
				$di=0;
				unset($downlinesk);
				$uplines_id=implode(",", $uplines);
				$t3=@mysql_num_rows($r3=mysql_query($s="select {$this->db_info['user_col']} from {$this->db_info['table']} where {$this->db_info['parent_user_col']} in ($uplines_id) AND ({$this->db_info['orderby_col']} <= {$this->width} AND {$this->db_info['orderby_col']} != '0')"));
				for($k=0;$k<$t3;$k++){
					$downlinek=mysql_fetch_assoc($r3);
					$downlinesk[$di++]=$downlinek['id'];
					$all_downlines[$downlinek["id"]]=$downlinek;
				}
				unset($uplines);
				$uplines = $downlinesk; //print_r($uplines);
			}while(count($uplines));
		}//print_r($all_downlines);
		$total_downline = count($all_downlines);
		
		return $total_downline;
	}

	function do_position() {
		//attach level 0 on the root
		$this->levels[0] = array(
			                   "max_nodes"   => 1,
			                   "downup_lines"=> array(
			                                      array(
                                                     $this->root_id=> 0
			                                      ) 
		                                        ),
			                   "position"    => array(0), 
			               );

        //attrach new one level

		if ($this->is_enable_placement) {
		   $this->levels[count($this->levels)] = array("max_nodes"=>1, "downup_lines"=>array(array("")), "position"=>array(),"total_downlines"=>array());
		}

		ksort($this->levels);

		//assign position for each level
		foreach ($this->levels as $level_num => &$level) {

			$prev_level       = $this->levels[$level_num - 1] OR $prev_level = NULL;

			$prev_total_nodes = ($prev_level == NULL) ? 1 : $prev_level["total_draw_nodes"];
			$nodes            = $level["downup_lines"];
			$parent_nodes     = array_keys($nodes);
			$max_nodes        = ($level_num == 0 ) ? 1 : max($level["max_nodes"],$this->width);

			$level["total_draw_nodes"] = $prev_total_nodes * $max_nodes;
            
            if ($prev_level != NULL) {

				$prev_level_position = $prev_level["position"];
                $position = 0;

				for($i=1; $i<=count($prev_level_position); $i++) {

					$upline_id = current($prev_level_position);
                    $down_nodes = is_array($nodes[$upline_id]) ? array_flip($nodes[$upline_id]) : array();

                    foreach ( range(1, $max_nodes) as $n )  {  

						if ( isset($down_nodes[$n]) ) {
							$level["position"][$position] = $down_nodes[$n];
							$level["total_downlines"][$position] = (int)$this->get_total_downline_by_leg( $down_nodes[$n] );

						} else {
							$level["position"][$position] = 0;
							$level["total_downlines"][$position] = 0;
						}

						$position++;
					}

					next($prev_level_position);
                   
				}

		    } else {
                $level["position"] = array_flip(current($nodes));
			}
		}

	}
  
	function display_UI() {
        //draw UI level by level in server side, without line !!! under construction
	}

	function JS_draw_vertical() {
		ob_start();
?>
                //draw vertical connector

				for (var userID in vConnector)
				{
				   node = vConnector[userID];
				   imgID = node.imgID;
				   imgNode = document.getElementById(node.imgID);

				   imgNode.onmouseover = function() {

				       this.title = ""; //this to fix IE display alt text as tooltip
				       var rankName = oRankName[oUsers[this.alt].rank];
				       if (rootID != this.alt && oUsers[ this.alt ].total_downlines > 0) this.style.cursor='pointer';
				       document.getElementById("tooltip").innerHTML = "Name: " + oUsers[this.alt].name + "<br/>"
					                                                + "ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: " + oUsers[this.alt].id + "<br/>"
																	+ "Rank&nbsp;: " +  (rankName == undefined ? "N/A" : rankName)+ "<br/>"
																	+ "Total Downlines : " + oUsers[this.alt].total_downlines+ "<br />"
																	+ "Sales (Plan A): " + oUsers[this.alt].sales_plana+ "<br />"
																	+ "Sales (Plan B): " + oUsers[this.alt].sales_planb+ "<br />";
				   }
                   
				   if (rootID != imgNode.alt && oUsers[imgNode.alt].total_downlines > 0)  {
					   imgNode.onclick = function() {					      
						   var root_id = this.alt;
						   document.location = "<?php echo $this->script?>&root_id=" + root_id + extraParams;
					   }
				   }

                   if ((isPlacement == 0) || (isPlacement==1 && userID.indexOf("r_") == -1)) {
						$.tooltip({mainElement:imgID, tipElement:'tooltip',top:'10',left:'15'});
				   }
				   parentID = node.parentID;
				   parentNode = vConnector[parentID];
	 
				   if (parentNode!=undefined)
				   {
                       var row = document.getElementById( node.trID );
					   var parentRow = document.getElementById( parentNode.trID );

					   if (parentRow.lang != "added") {

					   	   var slotLine = document.createElement("div");
    				       slotLine.className = "slot_line";					   

						   parentRow.appendChild(slotLine);
						   parentRow.lang = "added";
                       }

					   var slotLine = document.createElement("div");
    				   slotLine.className = "clear";
					   row.insertBefore( slotLine, imgNode );

                       var slotLine = document.createElement("div");
    				   slotLine.className = "slot_line";								  					
					   row.insertBefore( slotLine, imgNode );
				   } else {
                       if (aUp != undefined) {
						   var row = document.getElementById( node.trID );

						   var divUp = document.createElement("div");
						   divUp.appendChild(aUp);
						   divUp.style.display = "block";

						   row.insertBefore(divUp, imgNode);

					   }
				   }
				}										
			

<?php
	    return ob_get_clean();
	}

	function JS_draw_horizontal() {

		ob_start();
		//draw horizontal connector		
?>		
				if (isPlacement == 0) {
				    
					var trs = document.getElementById("gtable").getElementsByTagName("tr");					

					for(var i =0; i < trs.length; i++) {

						var tds = trs[i].getElementsByTagName("td");


						var tdLength = tds.length;
						var tdLengthPerBlock = Math.floor (tdLength/width);

						if (tdLengthPerBlock != 0) {
                            var trIdx = 0;
							for (var x=0; x < tdLengthPerBlock; x++) {
                                
								center = width / 2;
								//loop each node in block, start from left
								var start = false;
								var from = x * width;
							    for(var y=0; y < width && (y < center); y++) {
								 
									var td = tds[from];

								    if (!start) {
									    var oImg = td.getElementsByTagName("img")[0];

									    if (oImg && oImg.alt != "" && center - y != 0.5) {

											var slotLine = document.createElement("div");
											slotLine.className = "slot_connector_left";
											td.insertBefore(slotLine, oImg);				
											
											start=true;
									    }										
									} else {

										var oEle = td.getElementsByTagName("img")[0] || td.getElementsByTagName("div")[0];
                                        var slotLine = document.createElement("div");
										slotLine.className = (center - y == 0.5) ? "slot_connector_right" : "slot_connector_center";
									    td.insertBefore(slotLine, oEle);	
										td.vAlign = "top";

										
									}
									from++;				    
							    }
                                start = false;
                                from = (x * width) + width - 1;
								//loop each node in block, start from right
								for (var y=width-1; y >= 0 && (y >= center || y - center == -0.5 ); y--) {								    
									var td = tds[from];
								    if (!start) {
									    var oImg = td.getElementsByTagName("img")[0];

									    if (oImg && oImg.alt != "" && y - center != -0.5) {
										    var slotLine = document.createElement("div");
											slotLine.className = "slot_connector_right";
											start=true;
											td.insertBefore(slotLine, oImg);									    								
										}									
									} else {
									    var oEle = td.getElementsByTagName("img")[0] || td.getElementsByTagName("div")[0];
                                        var slotLine = document.createElement("div");
										slotLine.className = ( y - center == -0.5 ) ? "slot_connector_left" : "slot_connector_center";
										td.insertBefore(slotLine, oEle);	
										td.vAlign = "top";
									}
									from--;
								}
							}						
						}
					}
					
				} else {
						
					var trs = document.getElementById("gtable").getElementsByTagName("tr");					

					for(var i=1; i < trs.length;i++) {

						var tds = trs[i].getElementsByTagName("td");
						var y = 1;

						for(var j=0; j < tds.length; j++) {

							var td = tds[j];
							var content = td.innerHTML;
								
							var element = null;
							var oImg = td.getElementsByTagName("img")[0];

							if (oImg && oImg.alt != "") {
								element = td.getElementsByTagName("img")[0];
							} else if (td.getElementsByTagName("input")[0]) {
								element  = td.getElementsByTagName("input")[0].parentNode;
							}                            						    
							if (element!=null) {							
								var slotLine = document.createElement("div");

								if (y==1) {
									slotLine.className = "slot_connector_left";
								} else if (y==width) {
									slotLine.className = "slot_connector_right";
								} else {
									slotLine.className = "slot_connector_center";
								}

								td.insertBefore(slotLine, element);
							}
								
							y++;

							if (y > width) y = 1;
						}
					}					
				}
<?php
        return ob_get_clean();
	}

	function run_JS() {
	    ob_start();
?>
			var oLevel = null;
			var oUsers = null;
			var oImgUrl = null;
			var oRankName = null;
			var vConnector = {};

			var width = <?php echo $this->width?>;
			var isPlacement = <?php echo (int)$this->is_enable_placement;?>;
			var isLeftRight = <?php echo (int)$this->is_enable_leftright;?>;
		
			var nodeImgWidth = <?php echo $this->node_image_width?>; 
			var nodeImgHeight = <?php echo $this->node_image_height?>; 

			var rootNodeImgWidth = <?php echo $this->root_node_image_width?>; 
			var rootNodeImgHeight = <?php echo $this->root_node_image_height?>; 

			var rootNodeImgUrl="<?php echo $this->root_node_image_url?>";
			var rootID = <?php echo $this->root_id?>;

			var placePos = {};

			var goDownLinks = "<?php echo $this->go_down_links?>";
			var goUpLinks   = "<?php echo $this->go_up_links?>";
			var upUserID    = "<?php echo $this->up_user_id?>";

            var extraParams = "&links=" + goDownLinks;

			var searchID = <?php echo $this->search_id?>;

			jQuery(document).ready(function($){	

				winwidth  = document.all?document.body.clientWidth:window.innerWidth;
				winHeight = document.all?document.body.clientHeight:window.innerHeight; 
				
				oLevel = jeval('<?php echo json_encode($this->levels)?>'); //decode string as json
				oUsers  = jeval('<?php echo json_encode($this->users)?>');
				oImgUrl = jeval('<?php echo json_encode($this->node_image_url)?>');
				oRankName = jeval('<?php echo json_encode($this->rank_name)?>');

				drawG();//start to draw genealogy chart

			});

			function jeval(str) { return eval('(' +  str + ')') }

			function getParentID(userID,uplines) {
				for(var parentID in uplines) {
					var parentNode = uplines[parentID];
					for(var _userID in parentNode) {
					  
						var node = parentNode[_userID];
						if (userID==_userID) 
						{
							return {"parentID": parentID};
						}
					}
				}
				return {};
			}

			function getMaxTotalNodes() {
				return (oLevel[oLevel.length-1].total_draw_nodes);
			}

			function drawG() {

				var max_total_nodes = getMaxTotalNodes();
				var Gtable = document.createElement("table");
				var Gbody = document.createElement("tbody");                 
				var n = 0;

				Gtable.border=0;
				Gtable.id = "gtable";
				Gtable.style.borderCollapse = "collapse";
				Gtable.cellSpacing = 0;
				Gtable.cellPadding = 0;
				Gtable.width = '1px';
				Gtable.style.margin = "auto";

				/**
				 * 
					 1) Assign both real node and fake node level by level
					 2) Reassign node in hierachy-form for ease of drawing line
					 3) Assign next level's position that have placement if isPlacement is set to true
				 */

				for (var level in oLevel)
				{
				    levelNum = parseInt( level );
					level = oLevel[levelNum];
					var nextLevel = oLevel[levelNum + 1];
				
					var colSpan =  max_total_nodes/ level.total_draw_nodes;
					var Gtr = document.createElement("tr");
					var fixedWidth = 100/level.total_draw_nodes;			
					
					var tempParentID = 0;
					var parent = {};					
					
					if (isPlacement == 1) {

						tempPlacePos = placePos;
						placePos = {};

						for(var node in level.position) {

							n++
							var Gtd = document.createElement("td");
							var userID = level.position[node];
							node = parseInt(node);
							var _node = node + 1;
				   
							if (userID == 0 ) {
								
								var prevPosition = Math.floor (node / width);

								if (tempPlacePos[prevPosition]==undefined) {

								    var attachObj = document.createElement("div");

								    attachObj.id = "fake_node_" + n;
								    attachObj.style.width = nodeImgWidth + "px";
								    attachObj.style.height = nodeImgHeight + "px";

								} else {

								    Gtd.id = "tr2_" + n; 

									parentID = tempPlacePos[prevPosition];

								    var attachObj = document.createElement("div");

								    attachObj.id = "fake_node_" + n;
								    attachObj.style.width = nodeImgWidth + "px";
								    attachObj.style.height = nodeImgHeight + "px";
								    attachObj.alt = "@downline";

								    var r = document.createElement("input");
								    r.type = "radio";
								    r.name = "placenodes";
								    attachObj.appendChild(r);
									 
                                    vConnector['r_' + n] = {"parentID":parentID, "imgID":attachObj.id, "trID":Gtd.id};
								}
							} else {

								var attachObj = document.createElement("img");
								var parent = getParentID(userID,level.downup_lines);		 
								Gtd.id = "tr_" + userID;

								attachObj.id = "node_" + userID;
								attachObj.src= oImgUrl[oUsers[userID].rank];
								attachObj.alt = userID;
								
								vConnector[userID] = {"parentID":parent.parentID, "imgID":attachObj.id, "trID":Gtd.id}	;							
								//push parent position that has node

								placePos[node]=userID;

							}

							Gtd.appendChild(attachObj);
							Gtd.colSpan = colSpan;
						    Gtd.style.width = fixedWidth + "%";
							Gtd.vAlign = "top";
							Gtd.align   = "center";
								
							Gtr.appendChild(Gtd);
						}

                    } else { //isPlacement = false

						for(var node in level.position) {
							
							n++
							node = parseInt(node);
							var Gtd = document.createElement("td");
							var userID = level.position[node];							
							var _node = node + 1;
							
							if (userID == 0 ) {		
							
							    var attachObj = document.createElement("div");

								attachObj.id = "fake_node_" + n;
								attachObj.style.width = nodeImgWidth + "px";
								attachObj.style.height = nodeImgHeight + "px";
                                 															
							} else {
							    
							    Gtd.id = "td_" + userID;
								tempParentID = (parent.parentID!=undefined) ? parent.parentID : 0;
								var parent = getParentID(userID,level.downup_lines);              

								var attachObj = document.createElement("img");
								attachObj.id  = "node_" + userID;
                                attachObj.src = oImgUrl[oUsers[userID].rank];
								attachObj.alt = userID;
								attachObj.style.border = (searchID == userID) ? "thin dotted #000000" : "";
																						    							
								vConnector[userID] = {"parentID":parent.parentID, "imgID":attachObj.id, "trID":Gtd.id}	;							
							}

							Gtd.appendChild(attachObj);
							Gtd.innerHTML += ((nextLevel == undefined && oUsers[userID]!= undefined && oUsers[userID].total_downlines != undefined && oUsers[userID].total_downlines>0) ? 
							  "<br/><a href='<?php echo $this->script?>&root_id=" + userID +  extraParams +"'><img src='<?php echo $this->img_url?>more.gif'/></a>" 
							  : 
							  "");

							Gtd.vAlign = "top";
							Gtd.colSpan = colSpan;
						    Gtd.style.width = fixedWidth + "%";
							Gtd.align   = "center";
							
						    Gtr.appendChild(Gtd);
						} //end of loop thru each level
					} //end of isPlacement				
					Gbody.appendChild(Gtr);
				} //end for loop level

				Gtable.appendChild(Gbody);	

                if (upUserID != "") {
				    var aUp = document.createElement("a");
					aUp.href = "<?php echo $this->script?>&root_id=" + upUserID + "&links=" + goUpLinks;
					aUp.innerHTML = "<img src='<?php echo $this->img_url?>upmore.gif'/>";                   
					document.getElementById("body").appendChild( aUp );
				}

				document.getElementById("body").appendChild(Gtable);
			   
                <?php echo $this->JS_draw_horizontal();?>
				<?php echo $this->JS_draw_vertical();  ?>
			}

            function debug(trace_msg) {
			    document.getElementById("debug").innerHTML += trace_msg + "<br/>";
			}


			

<?php
        return ob_get_clean();
	} //end of function run_JS
}
?>